}
}
+static GdkWindow *
+get_current_toplevel (GdkDisplay *display,
+ int *x_out, int *y_out,
+ GdkModifierType *state_out)
+{
+ GdkWindow *pointer_window;
+ GdkWindowObject *w;
+ int x, y;
+ GdkModifierType state;
+
+ pointer_window = _gdk_windowing_window_at_pointer (display, &x, &y, &state);
+ if (pointer_window != NULL &&
+ (GDK_WINDOW_DESTROYED (pointer_window) ||
+ GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
+ GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
+ pointer_window = NULL;
+
+ w = (GdkWindowObject *)pointer_window;
+ if (w)
+ {
+ /* Convert to toplevel */
+ while (w->parent != NULL &&
+ w->parent->window_type != GDK_WINDOW_ROOT)
+ {
+ x += w->x;
+ y += w->y;
+ w = w->parent;
+ }
+ }
+
+ *x_out = x;
+ *y_out = y;
+ *state_out = state;
+ return (GdkWindow *)w;
+}
+
static void
switch_to_pointer_grab (GdkDisplay *display,
GdkPointerGrabInfo *grab,
guint32 time,
gulong serial)
{
- GdkWindow *src_window, *pointer_window;
- GdkWindowObject *w;
+ GdkWindow *src_window, *pointer_window, *new_toplevel;
GList *old_grabs;
GdkModifierType state;
int x, y;
src_window, grab->window,
GDK_CROSSING_GRAB, time, serial);
}
-
+
/* !owner_event Grabbing a window that we're not inside, current status is
now NULL (i.e. outside grabbed window) */
if (!grab->owner_events && display->pointer_info.window_under_pointer != grab->window)
_gdk_display_set_window_under_pointer (display, NULL);
}
-
+
grab->activated = TRUE;
}
- else if (last_grab)
+
+ if (last_grab)
{
- pointer_window = _gdk_windowing_window_at_pointer (display, &x, &y, &state);
- if (pointer_window != NULL &&
- (GDK_WINDOW_DESTROYED (pointer_window) ||
- GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
- GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
- pointer_window = NULL;
-
- /* We force checked what window we're in, so we need to
- * update the toplevel_under_pointer info, as that won't get told of
- * this change.
- */
- if (display->pointer_info.toplevel_under_pointer)
- g_object_unref (display->pointer_info.toplevel_under_pointer);
- display->pointer_info.toplevel_under_pointer = NULL;
-
- if (pointer_window)
+ new_toplevel = NULL;
+
+ if (grab == NULL /* ungrab */ ||
+ (!last_grab->owner_events && grab->owner_events) /* switched to owner_events */ )
+ {
+ /* We force check what window we're in, and update the toplevel_under_pointer info,
+ * as that won't get told of this change with toplevel enter events.
+ */
+ if (display->pointer_info.toplevel_under_pointer)
+ g_object_unref (display->pointer_info.toplevel_under_pointer);
+ display->pointer_info.toplevel_under_pointer = NULL;
+
+ new_toplevel = get_current_toplevel (display, &x, &y, &state);
+ if (new_toplevel)
+ {
+ /* w is now toplevel and x,y in toplevel coords */
+ display->pointer_info.toplevel_under_pointer = g_object_ref (new_toplevel);
+ display->pointer_info.toplevel_x = x;
+ display->pointer_info.toplevel_y = y;
+ display->pointer_info.state = state;
+ }
+ }
+
+ if (grab == NULL) /* Ungrabbed, send events */
{
- /* Convert to toplevel */
- w = (GdkWindowObject *)pointer_window;
- while (/*w->parent != NULL && */
- w->parent->window_type != GDK_WINDOW_ROOT)
+ pointer_window = NULL;
+ if (new_toplevel)
{
- x += w->x;
- y += w->y;
- w = w->parent;
+ /* Find (possibly virtual) child window */
+ pointer_window =
+ _gdk_window_find_descendant_at (new_toplevel,
+ x, y,
+ NULL, NULL);
}
- /* w is now toplevel and x,y in toplevel coords */
- display->pointer_info.toplevel_under_pointer = g_object_ref (w);
+ if (pointer_window != last_grab->window)
+ synthesize_crossing_events (display,
+ last_grab->window, pointer_window,
+ GDK_CROSSING_UNGRAB, time, serial);
- /* Find (possibly virtual) child window */
- pointer_window =
- _gdk_window_find_descendant_at ((GdkWindow *)w,
- x, y,
- NULL, NULL);
- }
+ /* We're now ungrabbed, update the window_under_pointer */
+ _gdk_display_set_window_under_pointer (display, pointer_window);
- if (pointer_window != last_grab->window)
- synthesize_crossing_events (display,
- last_grab->window, pointer_window,
- GDK_CROSSING_UNGRAB, time, serial);
-
- /* We're now ungrabbed, update the window_under_pointer */
- _gdk_display_set_window_under_pointer (display, pointer_window);
-
- if (last_grab->implicit_ungrab)
- generate_grab_broken_event (last_grab->window,
- FALSE, TRUE,
- NULL);
+ if (last_grab->implicit_ungrab)
+ generate_grab_broken_event (last_grab->window,
+ FALSE, TRUE,
+ NULL);
+ }
}
display->pointer_grabs = old_grabs;